home *** CD-ROM | disk | FTP | other *** search
- /*
- * (c) Copyright 1992 by Panagiotis Tsirigotis
- * All rights reserved. The file named COPYRIGHT specifies the terms
- * and conditions for redistribution.
- */
-
- static char RCSid[] = "$Id: ident.c,v 5.1 1992/11/01 00:01:21 panos Exp $" ;
-
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <netdb.h>
- #include <signal.h>
- #include <syslog.h>
- #include <setjmp.h>
- #include <errno.h>
- #include <fcntl.h>
- #include <string.h>
- #include <ctype.h>
-
- #include "str.h"
-
- #include "defs.h"
- #include "server.h"
-
- void msg() ;
-
-
- #define TIME_LIMIT 10 /* seconds */
- #define BUFSIZE 512
-
- #define START_TIMER() (void) alarm( TIME_LIMIT )
- #define STOP_TIMER() (void) alarm( 0 )
-
- char *inet_ntoa() ;
-
- status_e write_buf() ;
-
-
- static jmp_buf env ;
-
-
- static void sigalrm_handler()
- {
- longjmp( env, 1 ) ;
- }
-
-
- /*
- * This function always runs in a forked process.
- */
- void log_remote_user( serp )
- struct server *serp ;
- {
- static char buf[ BUFSIZE ] ;
- int cc ;
- struct sockaddr_in sin_local, sin_remote, sin_contact ;
- unsigned local_port, remote_port ;
- int sd ;
- int sin_len ;
- char *p ;
- char *func = "log_remote_user" ;
- char *get_line(), *verify_line() ;
- void logprint() ;
-
- if ( (int) signal( SIGALRM, sigalrm_handler ) == -1 )
- {
- msg( LOG_ERR, func, "signal: %m" ) ;
- return ;
- }
-
- /*
- * Determine local and remote addresses
- */
- sin_len = sizeof( sin_local ) ;
- if ( getsockname( SERVER_FD( serp ), SA( &sin_local ), &sin_len ) == -1 )
- {
- msg( LOG_ERR, func, "getsockname: %m" ) ;
- return ;
- }
- sin_remote = *conn_address( SERVER_CONNECTION( serp ) ) ;
- local_port = ntohs( sin_local.sin_port ) ;
- remote_port = ntohs( sin_remote.sin_port ) ;
-
- /*
- * Create a socket and set the close-on-exec flag on the descriptor
- */
- sd = socket( AF_INET, SOCK_STREAM, 0 ) ;
- if ( sd == -1 )
- {
- msg( LOG_ERR, func, "socket creation: %m" ) ;
- return ;
- }
- if ( fcntl( sd, F_SETFD, 1 ) == -1 )
- {
- msg( LOG_ERR, func, "fcntl F_SETFD: %m" ) ;
- return ;
- }
-
- if ( setjmp( env ) )
- {
- msg( LOG_ERR, func, "Timeout while contacting identity server at %s",
- inet_ntoa( sin_remote.sin_addr ) ) ;
- return ;
- }
-
- CLEAR( sin_contact ) ;
- sin_contact.sin_family = sin_remote.sin_family ;
- sin_contact.sin_addr = sin_remote.sin_addr ;
- sin_contact.sin_port = htons( IDENTITY_SERVICE_PORT ) ;
-
- START_TIMER() ;
-
- if ( connect( sd, SA( &sin_contact ), sizeof( sin_contact ) ) == -1 )
- {
- STOP_TIMER() ;
- return ;
- }
-
- cc = strx_nprint( buf, sizeof( buf ),
- "%d,%d\r\n", remote_port, local_port ) ;
- if ( write_buf( sd, buf, cc ) == FAILED )
- {
- STOP_TIMER() ;
- return ;
- }
-
- if ( get_line( sd, buf, sizeof( buf ) ) == NULL )
- {
- STOP_TIMER() ;
- return ;
- }
-
- STOP_TIMER() ;
-
- /*
- * Verify that the received line is OK
- */
- if ( ( p = verify_line( buf, local_port, remote_port ) ) == NULL )
- {
- msg( LOG_ERR, func, "Bad line received from identity server at %s: %s",
- inet_ntoa( sin_remote.sin_addr ), buf ) ;
- return ;
- }
-
- logprint( SERVER_CONNECTION( serp )->sp, "USERID", "%s", p ) ;
- }
-
-
- PRIVATE char *verify_line( line, local_port, remote_port )
- char *line ;
- unsigned local_port ;
- unsigned remote_port ;
- {
- char *p ;
- char *start = line ;
-
- /*
- * Verify port numbers
- */
- p = strchr( start, ',' ) ;
- if ( p == NULL )
- return( NULL ) ;
- *p = NUL ;
- if ( atoi( start ) != remote_port )
- return( NULL ) ;
-
- start = p+1 ;
- p = strchr( start, ':' ) ;
- if ( p == NULL )
- return( NULL ) ;
- *p = NUL ;
- if ( atoi( start ) != local_port )
- return( NULL ) ;
-
- start = p+1 ;
- for ( p = start ; isspace( *p ) ; p++ ) ;
- if ( *p == NUL )
- return( NULL ) ;
- start = p ;
- if ( strncmp( start, "USERID", 6 ) != 0 )
- return( NULL ) ;
- start += 6 ; /* skip the USERID */
-
- /*
- * Skip any white-space
- */
- for ( p = start ; isspace( *p ) ; p++ ) ;
- if ( *p != ':' )
- return( NULL ) ;
- for ( p++ ; isspace( *p ) ; p++ ) ;
- if ( *p == NUL )
- return( NULL ) ;
- return( p ) ;
- }
-
-
-
- /*
- * Get a line terminated by CR-LF.
- * Replace the CR-LF with NUL.
- */
- PRIVATE char *get_line( sd, buf, bufsize )
- int sd ;
- char *buf ;
- unsigned bufsize ;
- {
- int size ;
- int cc ;
- char *p ;
- char *s ;
- char *func = "get_line" ;
-
- for ( p = buf, size = bufsize ; size > 0 ; p += cc, size -= cc )
- {
- cc = read( sd, p, size ) ;
- if ( cc == -1 )
- if ( errno == EINTR )
- {
- cc = 0 ;
- continue ;
- }
- else
- {
- msg( LOG_ERR, func, "read: %m" ) ;
- return( NULL ) ;
- }
- for ( s = p ; s < p + cc ; s++ )
- if ( *s == '\n' && s != buf && s[-1] == '\r' )
- {
- s[-1] = NUL ;
- return( buf ) ;
- }
- }
- msg( LOG_ERR, func, "Too much input from identity server" ) ;
- return( NULL ) ;
- }
-
-